const cp = require('child_process'),
      Qiniu = require('qiniu'),
      crypto = require('crypto');  //node加密工具

const { resolve } = require('path');
const { nanoid } = require('nanoid');
const {qiniu, cryptoSecret } = require('../config/config');
const qiniuKeys = qiniu.keys;

//service
const ProblemTypeService = require('../services/ProblemType');


/* 子进程控制函数 */
function startProcess (options) {
  //参数列表
  //options file message exit error
  const script = resolve(__dirname, '../controllers/crawlers/' + options.file),
        //通过路径引入脚本 传入三个处理函数
        child = cp.fork(script, []);

  let invoked = false;

  child.on('message', (data) => {
    options.message(data);
  });

  child.on('exit', (code) => {
    if(invoked){
      return ;
    }

    invoked = true;
    options.exit(code);
  });

  child.on('error', (err) => {
    if(invoked){
      return ;
    }
    invoked = true;
    options.error(err);
  });
}


//七牛上传函数
function qiniuUpload (options) {
  const mac = new Qiniu.auth.digest.Mac(qiniuKeys.ak, qiniuKeys.sk),
        conf = new Qiniu.conf.Config(),
        client = new Qiniu.rs.BucketManager(mac, conf),
        key = nanoid() + options.ext; //文件名+ 后缀
  return new Promise((resolve, reject) => {
    client.fetch(options.url, options.bucket, key, (error, ret, info) => {
      if(error){
        reject(error);
      }else {
        // console.log(info.statusCode)
        if(info.statusCode === 200){
          resolve( {key} );
        }else {
          reject(info);
        }
      }
    })
  })
}

/* 加密函数 crypto是自带的加密模块*/
function makeCrypto (str) {
  const _md5 = crypto.createHash('md5'), //用md5方式创建hash
        content = `str=${str}&secret=${cryptoSecret}`; //用url参数的方式去加
  //只要加密就行，只要用户输入的密码通过这种方式加密，等于数据库里的密码就行
  return _md5.update(content).digest('hex'); //hex十六进制的方式
}      

/* 返回信息的函数*/
function returnInfo (errorInfo, data) {
  //把数据添加到信息里面去
  if (data) {
    errorInfo.data = data;
  }

  return errorInfo;
}

/* 去空格*/
function trimSpace (str) {
  return str.replace(/\s+/g, '');
}

/* 添加题目类型*/
async function addProblemType (problemList) {
  const problem_type = await ProblemTypeService.getAllProblemType();

    // 添加type字段 problemTypeId ->  type
    const typeObj = {};

    problem_type.forEach((item, index) => {
      typeObj[item.id] = item.type_title;
    });

    problemList.map((item, index) => {
      item.type = typeObj[item.problemTypeId];
      return item;
    })

    return problemList;
}


module.exports = {
  startProcess,
  qiniuUpload,
  makeCrypto,
  returnInfo,
  trimSpace,
  addProblemType
}